<?php

namespace Lib\MySlim\Middleware;

use RedBean_Facade as R;
use Symfony\Component\Yaml\Parser;
use Lib\MyHelper;

/**
 * Configurator
 * 
 * 读取配置文件，设置模板引擎、数据库连接等
 * 
 * @author Kail
 */
class Configurator extends \Slim\Middleware
{
    protected function addRoutes($routesConfig) {
        $app = $this->app;
        
        $myhelper = new MyHelper;
        foreach ($routesConfig as $routeName=>$routeDef) {
            $via = isset($routeDef['via']) ? $routeDef['via'] : 'GET';
            $route = $app->addControllerRoute($routeDef['path'], $routeDef['callback'])->name($routeName);
            if (is_array($via)) {
                call_user_func_array([$route, 'via'], $via);
            } else {
                $route->via($via);
            }
            
            if (!isset($routeDef['middlewares'])) continue;
            
            foreach ($routeDef['middlewares'] as $middleware) {
                if (strpos($middleware, '.') !== false) {
                    die('not support route middleware besides myhelper for now');
                } else {
                    $route->setMiddleware([$myhelper, $middleware]);
                }
            }
        }
    }
    
    protected function addHooks($hooksConfig) {
        $app = $this->app;
        foreach ($hooksConfig as $hook=>$hookCallback) {
            $app->hook($hook, $hookCallback);
        }
    }
    
    public function call() {
        $app = $this->app;
        $rootDir = $app->config('root.dir');
        
        // 模板文件路径
        $app->config('templates.path', "$rootDir/app/views");
        $app->config('view', new \Slim\Views\Twig());
        $view = $app->view();
        $view->parserOptions = array(
            'debug' => true,
            'cache' => "$rootDir/app/cache"
        );
        $view->parserExtensions = array(
            new \Slim\Views\TwigExtension(),
            new \Lib\MyTwigExtension(),
        );
        
        $yaml = new Parser();
        // 先导入parameters.yml
        $paramsFilePath = "$rootDir/app/config/parameters.yml";
        if (file_exists($paramsFilePath)) {
            $config = $yaml->parse(file_get_contents($paramsFilePath));
            $_configParams = $config['parameters'];
            if (isset($_configParams['twig'])) {
                $twigEnv = $view->getEnvironment();
                foreach ($_configParams['twig'] as $varName=>$varVal) {
                    $twigEnv->addGlobal($varName, $varVal);
                }
            }
            unset($_configParams['twig']);
            $app->config($_configParams);
            
            $this->addRoutes($_configParams['routes']);
        }
        
        // 再导入对应mode下parameters
        $mode = $app->getMode();
        $parametersFilePath = "$rootDir/app/config/parameters_$mode.yml";
        if (!file_exists($parametersFilePath)) {
            die("parameters_$mode.yml not exist");
        }
        $config = $yaml->parse(file_get_contents($parametersFilePath));
        
        $configParams = $config['parameters'];
        if (isset($configParams['routes'])) {
            $this->addRoutes($configParams['routes']);
        }
        $configParams = array_merge($_configParams, $configParams);
        $app->config($configParams);
        
        $db = $configParams['database_name'];
        $dbhost = $configParams['database_host'];
        $dbuser = $configParams['database_user'];
        $dbpswd = $configParams['database_password'];
        // utf8 or utf8mb4(only mysql5.5+ supports utf8mb4)
        if ($configParams['database_utf8mb4']) {
            $dbCharsetEncoding = 'CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci';
            $dbcharset = 'utf8mb4';
            $dbencoding ='utf8mb4';   
        } else {
            $dbCharsetEncoding = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci';
            $dbcharset = 'utf8';
            $dbencoding = 'utf8';
        }
        
        // create database if not exists(may not have the right)
        try {
            $dbh = new \PDO("mysql:host=$dbhost", $dbuser, $dbpswd);
            $dbh->exec("CREATE DATABASE IF NOT EXISTS `$db` $dbCharsetEncoding;
                    CREATE USER '$dbuser'@'$dbhost' IDENTIFIED BY '$dbpswd';
                    GRANT ALL ON `$db`.* TO '$dbuser'@'$dbhost';
                    FLUSH PRIVILEGES;")
            or die(print_r($dbh->errorInfo(), true));
        } catch (\PDOException $e) {
            die('DB ERROR: ' . $e->getMessage());
        }
        
        // setup redbean
        R::setup("mysql:host=$dbhost;dbname=$db;charset=$dbcharset;encoding:$dbencoding", $dbuser, $dbpswd);
        
        // @todo refactor
        $app->hook('slim.before.dispatch', function () use ($app) {
            $app->view->setData('app', $app);
            
            // @todo refactor!!
            if ($app->config('wxshare_enabled')) {
                $jssdk = new \Lib\JSSDK($app->config('wx_appid'), $app->config('wx_secret'));
                $app->view->setData('signPackage', $jssdk->GetSignPackage());
            }
        });
        
        $this->addHooks($configParams['hooks']);
        
        $this->next->call();
    }
}